package bm.com.project.server.common.service.impl;

import bm.com.framework.common.config.EnumCode;
import bm.com.framework.common.exception.BmException;
import bm.com.framework.redis.keys.RedisKey;
import bm.com.project.server.common.dto.BmSysChangeOrgReqDTO;
import bm.com.project.server.common.dto.BmSysLoginReqDTO;
import bm.com.project.server.common.dto.BmSysSignInReqDTO;
import bm.com.project.server.common.mapper.BmSysUserLoginTokenRecordMapper;
import bm.com.project.server.common.service.LoginService;
import bm.com.project.server.organization.entity.BmOrgDepartmentEntity;
import bm.com.project.server.organization.entity.BmOrgEntity;
import bm.com.project.server.organization.entity.BmOrgMemberEntity;
import bm.com.project.server.organization.mapper.BmOrgDepartmentMapper;
import bm.com.project.server.organization.mapper.BmOrgMapper;
import bm.com.project.server.organization.mapper.BmOrgMemberMapper;
import bm.com.project.server.organization.service.OrgService;
import bm.com.project.server.sys.entity.BmSysUserEntity;
import bm.com.project.server.sys.mapper.BmSysUserMapper;
import bm.com.framework.common.resp.PageVO;
import bm.com.framework.common.resp.Result;
import bm.com.framework.common.resp.ResultVO;
import bm.com.framework.common.unit.DateUnit;
import bm.com.framework.redis.unit.RedisUnits;
import bm.com.framework.common.unit.Tool;
import bm.com.framework.web.core.dto.BmSysUserTokenDTO;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@Service
public class LoginServiceImpl implements LoginService {

    @Resource
    BmSysUserMapper bmSysUserDao;

    @Resource
    BmSysUserLoginTokenRecordMapper bmSysUserLoginTokenRecordDao;

    @Resource
    BmOrgMapper bmOrgDao;

    @Resource
    BmOrgDepartmentMapper bmOrgDepartmentDao;

    @Resource
    BmOrgMemberMapper bmOrgMemberDao;

    @Resource
    RedisUnits redisUnits;

    @Resource
    OrgService orgService;


    /**
     * 用户注册
     *
     * @param sysSignInReqDTO
     * @return
     */
    @Override
    @Transactional(rollbackFor = {Exception.class})
    public Result<BmSysUserTokenDTO> signIn(BmSysSignInReqDTO sysSignInReqDTO) {

        /**
         * 截取手机后四位，拼接用户名
         */
        String strMobile = String.valueOf(sysSignInReqDTO.getMobile());
        String username = "半亩用户-" + strMobile.substring(6, 11);

        String orgTitle = sysSignInReqDTO.getOrgTitle();

        long time = DateUnit.getNowTimeSecond();
        String userId = Tool.iDGenerator();

        /** 保存用户基本信息 */
        BmSysUserEntity bmSysUserEntity = new BmSysUserEntity();
        bmSysUserEntity.setId(userId);
        bmSysUserEntity.setUsername(username);
        bmSysUserEntity.setMobile(sysSignInReqDTO.getMobile());
        bmSysUserEntity.setPassword(sysSignInReqDTO.getPassword());
        bmSysUserEntity.setStatus(1);
        bmSysUserEntity.setCreateDate(time);
        bmSysUserEntity.setUpdateDate(time);
        bmSysUserDao.insert(bmSysUserEntity);

        /** 保存组织架构信息 */
        Long expireDate = time + 86400 * 15;//有效期默认15天
        String orgId = Tool.iDGenerator();
        BmOrgEntity bmOrgEntity = new BmOrgEntity();
        bmOrgEntity.setId(orgId);
        bmOrgEntity.setCreatorId(userId);
        bmOrgEntity.setType(sysSignInReqDTO.getOrgType());
        bmOrgEntity.setIsAuthenticate(0);
        bmOrgEntity.setTitle(orgTitle);
        bmOrgEntity.setIndustryType(sysSignInReqDTO.getIndustryType());
        bmOrgEntity.setScale(sysSignInReqDTO.getScale());
        bmOrgEntity.setCreateDate(time);
        bmOrgEntity.setUpdateDate(time);
        bmOrgEntity.setExpireDate(expireDate);
        bmOrgDao.insert(bmOrgEntity);

        /** 保存组织架构信息 */
        String departmentId = Tool.iDGenerator();
        BmOrgDepartmentEntity bmOrgDepartment = new BmOrgDepartmentEntity();
        bmOrgDepartment.setId(departmentId);
        bmOrgDepartment.setOrgId(orgId);
        bmOrgDepartment.setUserId(userId);
        bmOrgDepartment.setTitle("未分配部门");
        bmOrgDepartment.setStatus(1);
        bmOrgDepartment.setType(1);
        bmOrgDepartment.setCreateDate(time);
        bmOrgDepartment.setUpdateDate(time);
        bmOrgDepartmentDao.insert(bmOrgDepartment);

        /** 保存组织成员信息 */
        String memberId = Tool.iDGenerator();
        BmOrgMemberEntity bmOrgMemberEntity = new BmOrgMemberEntity();
        bmOrgMemberEntity.setId(memberId);
        bmOrgMemberEntity.setUserId(userId);
        bmOrgMemberEntity.setOrgId(orgId);
        bmOrgMemberEntity.setIsManager(1);
        bmOrgMemberEntity.setDepartmentId(departmentId);
        bmOrgMemberEntity.setCreateDate(time);
        bmOrgMemberDao.insert(bmOrgMemberEntity);

        String token = Tool.generateToken();
        Map<String, Object> tokenMap = new HashMap<>();
        tokenMap.put("userId", userId);
        tokenMap.put("token", token);
        tokenMap.put("logo", "");
        tokenMap.put("username", username);
        tokenMap.put("orgId", orgId);
        tokenMap.put("orgManager", 1);
        tokenMap.put("orgExpireDate", expireDate);
        tokenMap.put("orgTitle", orgTitle);
        tokenMap.put("orgType", sysSignInReqDTO.getOrgType());

        /** 同步token信息 */
        BmSysUserTokenDTO bmSysUserTokenDTO = syncToken(tokenMap);

        return new Result<BmSysUserTokenDTO>().ok(bmSysUserTokenDTO);
    }

    /**
     * 获取组织列表
     * @param sysLoginReqDTO
     * @return
     */
    @Override
    public ResultVO getOrgLIst(BmSysLoginReqDTO sysLoginReqDTO) {

        BmSysUserEntity bmSysUserEntity = null;
        BmOrgEntity bmOrgEntity = null;

        /** 短信验证码登陆 */
        if (sysLoginReqDTO.getLoginType() == EnumCode.NUMBER_ONE) {

            bmSysUserEntity = bmSysUserDao.getUserByPassword(sysLoginReqDTO.getMobile(), sysLoginReqDTO.getPassword());
            if (Tool.isObjectEmpty(bmSysUserEntity)) {
                return ResultVO.error("查无该手机号用户信息");
            }
        } else {
            if (Tool.isIntEmpty(sysLoginReqDTO.getSmsVerifyCode())) {
                return ResultVO.error("短信验证码不能为空");
            }

            bmSysUserEntity = bmSysUserDao.getUserByMobile(sysLoginReqDTO.getMobile());
            if (!Tool.isObjectEmpty(bmSysUserEntity)) {
                return ResultVO.error("查无该手机号用户信息");
            }
        }

        /* 查询组织信息 */
        PageVO<List> orgList = orgService.getOrgList(sysLoginReqDTO.getOrgId());
        if (orgList.getCount() == 0) {
            return ResultVO.error("查无该组织信息");
        }

        return ResultVO.success(orgList.getList());
    }

    /**
     * 登录
     * @param sysLoginReqDTO
     * @return
     */
    @Override
    public Result<BmSysUserTokenDTO> login(BmSysLoginReqDTO sysLoginReqDTO) {

        BmSysUserEntity bmSysUserEntity = null;
        BmOrgEntity bmOrgEntity = null;

        /** 短信验证码登陆 */
        if (sysLoginReqDTO.getLoginType() == EnumCode.NUMBER_ONE) {
            if (Tool.isStringEmpty(sysLoginReqDTO.getPassword())) {
                return new Result<BmSysUserTokenDTO>().error("密码不能为空");
            }

            bmSysUserEntity = bmSysUserDao.getUserByPassword(sysLoginReqDTO.getMobile(), sysLoginReqDTO.getPassword());
            if (Tool.isObjectEmpty(bmSysUserEntity)) {
                return new Result<BmSysUserTokenDTO>().error("查无该手机号用户信息");
            }
        } else {
            if (Tool.isIntEmpty(sysLoginReqDTO.getSmsVerifyCode())) {
                return new Result<BmSysUserTokenDTO>().error("短信验证码不能为空");
            }

            bmSysUserEntity = bmSysUserDao.getUserByMobile(sysLoginReqDTO.getMobile());
            if (!Tool.isObjectEmpty(bmSysUserEntity)) {
                return new Result<BmSysUserTokenDTO>().error("查无该手机号用户信息");
            }
        }

        /* 查询组成成员信息 */
        BmOrgMemberEntity orgUser = bmOrgMemberDao.getOrgUser(sysLoginReqDTO.getOrgId(), bmSysUserEntity.getId());
        if (Tool.isObjectEmpty(orgUser)) {
            return new Result<BmSysUserTokenDTO>().error("不是该组织成员");
        }

        /* 查询组织信息 */
        bmOrgEntity = bmOrgDao.selectById(sysLoginReqDTO.getOrgId());
        if (Tool.isObjectEmpty(bmOrgEntity)) {
            return new Result<BmSysUserTokenDTO>().error("查无该组织信息");
        }


        String token = Tool.generateToken();
        Map<String, Object> tokenMap = new HashMap<>();
        tokenMap.put("userId", bmSysUserEntity.getId());
        tokenMap.put("token", token);
        tokenMap.put("logo", bmOrgEntity.getId());
        tokenMap.put("username", bmSysUserEntity.getUsername());
        tokenMap.put("orgId", bmOrgEntity.getId());
        tokenMap.put("orgExpireDate", bmOrgEntity.getExpireDate());
        tokenMap.put("orgTitle", bmOrgEntity.getTitle());
        tokenMap.put("orgManager", orgUser.getIsManager());
        tokenMap.put("orgType", bmOrgEntity.getType());

        // 同步信息到 security 中
        try{

            UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(bmSysUserEntity.getUsername(), bmSysUserEntity.getPassword());
            SecurityContextHolder.getContext().setAuthentication(authentication);
//            Authentication authenticate = authenticationManager.authenticate(authentication);

        } catch (BmException e){
            log.info("用户登录认证 security 错误信息 ： {}", e.getMessage());
        }


        /** 同步token信息 */
        BmSysUserTokenDTO bmSysUserTokenDTO = syncToken(tokenMap);

        return new Result<BmSysUserTokenDTO>().ok(bmSysUserTokenDTO);
    }

    /**
     * 切换组织
     * @param bmSysChangeOrgReqDTO
     * @param token
     * @return
     */
    @Override
    public Result<BmSysUserTokenDTO> changeOrg(BmSysChangeOrgReqDTO bmSysChangeOrgReqDTO, String token) {

        if (Tool.isStringEmpty(bmSysChangeOrgReqDTO.getOrgId())) {
            return new Result<BmSysUserTokenDTO>().error("组织唯一标识不能为空");
        }

        String userToken = redisUnits.get(RedisKey.sysUserToken(token));
        if (Tool.isStringEmpty(userToken)) {
            return new Result<BmSysUserTokenDTO>().error("查无当前登陆者信息");
        }

        /* 查询组成成员信息 */
        BmOrgMemberEntity orgUser = bmOrgMemberDao.getOrgUser(bmSysChangeOrgReqDTO.getOrgId(), bmSysChangeOrgReqDTO.getUserId());
        if (Tool.isObjectEmpty(orgUser)) {
            return new Result<BmSysUserTokenDTO>().error("不是该组织成员");
        }

        /* 查询组织信息 */
        BmOrgEntity bmOrgEntity = bmOrgDao.selectById(bmSysChangeOrgReqDTO.getOrgId());
        if (Tool.isObjectEmpty(bmOrgEntity)) {
            return new Result<BmSysUserTokenDTO>().error("查无该组织信息");
        }

        BmSysUserEntity bmSysUserEntity = bmSysUserDao.selectById(bmSysChangeOrgReqDTO.getUserId());
        if (!Tool.isObjectEmpty(bmSysUserEntity)) {
            return new Result<BmSysUserTokenDTO>().error("查无该用户信息");
        }

        String changeToken = Tool.generateToken();
        Map<String, Object> tokenMap = new HashMap<>();
        tokenMap.put("userId", bmSysUserEntity.getId());
        tokenMap.put("token", changeToken);
        tokenMap.put("logo", bmOrgEntity.getLogo());
        tokenMap.put("username", bmSysUserEntity.getUsername());
        tokenMap.put("orgManager", orgUser.getIsManager());
        tokenMap.put("orgId", bmOrgEntity.getId());
        tokenMap.put("orgExpireDate", bmOrgEntity.getExpireDate());
        tokenMap.put("orgTitle", bmOrgEntity.getTitle());
        tokenMap.put("orgType", bmOrgEntity.getType());

        /** 同步token信息 */
        BmSysUserTokenDTO bmSysUserTokenDTO = syncToken(tokenMap);
        return new Result<BmSysUserTokenDTO>().ok(bmSysUserTokenDTO);
    }

    /**
     * 同步token信息
     *
     * @param param
     * @return
     */
    public BmSysUserTokenDTO syncToken(Map<String, Object> param) {

        if (param.isEmpty()) {
            return null;
        }

        BmSysUserTokenDTO bmSysUserTokenDTO = new BmSysUserTokenDTO();
        bmSysUserTokenDTO.setToken(String.valueOf(param.get("token")));
        bmSysUserTokenDTO.setUserId(String.valueOf(param.get("userId")));
//        bmSysUserTokenDTO.setLogo((String) param.get("logo"));
        bmSysUserTokenDTO.setUsername(String.valueOf(param.get("username")));
        bmSysUserTokenDTO.setOrgManager((int) param.get("orgManager"));
        bmSysUserTokenDTO.setOrgId(String.valueOf(param.get("orgId")));
        bmSysUserTokenDTO.setOrgExpireDate((Long) param.get("orgExpireDate"));
        bmSysUserTokenDTO.setOrgTitle(String.valueOf(param.get("orgTitle")));
        bmSysUserTokenDTO.setOrgType((int) param.get("orgType"));

//        /** 保存用户登录的token记录信息 */
//        BmSysUserLoginTokenRecordEntity tokenRecord = new BmSysUserLoginTokenRecordEntity();
//        tokenRecord.setId(Tool.iDGenerator());
//        tokenRecord.setToken(String.valueOf(param.get("token")));

////        tokenRecord.setDiv(1);
//        tokenRecord.setUserId(String.valueOf(param.get("userId")));
//        tokenRecord.setCreateTime(String.valueOf(DateUnit.getNowTimeMilliSecond()));
////        bmSysUserLoginTokenRecordDao.insert(tokenRecord);

        String tokenJson = Tool.toJson(bmSysUserTokenDTO);
        redisUnits.set(RedisKey.sysUserToken((String) param.get("token")), tokenJson, EnumCode.TIME_864000);
        return bmSysUserTokenDTO;
    }

    /**
     * 用户退出
     * @param bmSysUserTokenDTO
     * @return
     */
    @Override
    public boolean loginOut(BmSysUserTokenDTO bmSysUserTokenDTO) {

        if(Tool.isStringEmpty(bmSysUserTokenDTO.getToken())){
            return false;
        }

//        redisUnits.del(RedisKey.sysUserToken(bmSysUserTokenDTO.getToken()));
        return true;
    }

}
